

module sdram_init #(
    parameter tRP = 2,
    parameter tRC = 6,
    parameter tMRD = 2,
    parameter tCAS = 3'd2
)(
    input       clk,
    input       rst_n,
    output      cmd_pre,
    output      cmd_ref,
    output      cmd_mrs,
    output      cs,
    output      init_end
);

    typedef enum {IDLE, PRE, REF, MRS, INIT_END, NOP} init_state_t;

    init_state_t init_state;
    init_state_t nop_state_n;
    logic [13:0] counter;
    logic refresh1;
    logic init_end_r;
    logic cs_r;
    assign cmd_pre = init_state == PRE;
    assign cmd_ref = init_state == REF;
    assign cmd_mrs = init_state == MRS;
    assign init_end  = init_end_r;
    assign cs      = cs_r;

    always_ff @(posedge clk)begin
        if(~rst_n)begin
            init_state <= IDLE;
            counter <= 10000;
            refresh1 <= 1'b0;
            nop_state_n <= IDLE;
            init_end_r <= 1'b0;
            cs_r          <= 0;
        end
        else begin
            if(counter != 0)begin
                counter <= counter - 1;
            end
            case(init_state)
            IDLE:begin
                if(counter == 0)begin
                    init_state <= NOP;
                    nop_state_n <= PRE;
                end
            end
            NOP: begin
                if(counter == 0) init_state <= nop_state_n;
            end
            PRE: begin
                init_state <= NOP;
                counter <= tRP - 2;
                nop_state_n <= REF;
            end
            REF: begin
                if(~refresh1)begin
                    nop_state_n <= REF;
                    refresh1 <= 1'b1;
                end
                else begin
                    nop_state_n <= MRS;
                end
                init_state <= NOP;
                counter <= tRC - 1;
            end
            MRS: begin
                init_state <= NOP;
                if(cs_r)begin
                    nop_state_n <= INIT_END;
                    init_end_r <= 1'b1;
                end
                else begin
                    nop_state_n <= IDLE;
                    cs_r <= 1'b1;
                end
                counter <= tMRD - 2;
            end
            endcase
        end
    end
endmodule